﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Foxit.PDF;
using Foxit.PDF.PageElements;
using Foxit.PDF.Imaging;
using Sustainalytics.ClientDW.Entities;
using System.Globalization;
using Sustainalytics.ESG.Entities;
using Sustainalytics.Reporting.Framework;
using System.Text;

namespace Sustainalytics.ReportGenerator.BL
{
    public class ControversiesSection : IPdfDocumentGenerator
    {
        private CompanyReportDataOffline _dataSource;
        private PdfReport _report;

        private readonly List<ControversyIndicatorLocation> _controversyIndicatorLocations = new List<ControversyIndicatorLocation>();
        private readonly List<EventIndicatorLocation> _eventIndicatorLocations = new List<EventIndicatorLocation>();

        private static Dictionary<int, EventIndicatorPropertiesVisibility> EventIndicatorPropertiesVisibilityDictionary { get; set; }
        private List<ControversyIndicator> ControversyIndicators { get; set; }

        
        #region Map Images
        private byte[] GetIncidentsMapImage(Guid eventIndicatorId)
        {

            if (_dataSource == null || _dataSource.EventIndicators == null)
                return null;

            var eventIndicator = _dataSource.EventIndicators.FirstOrDefault((e) => e.Id == eventIndicatorId);
            if (eventIndicator == null)
                return null;


            var imagesGenerator = new ImagesGenerator();
            var resultImage = imagesGenerator.GetSingleIncidentMapImageSmall(eventIndicator.Locations);

            return resultImage;
        }

        #endregion

        #region Charts Images

        public Dictionary<Guid, byte[]> IncidentsChartImages { get; set; }

        public byte[] GetIncidentsChartImage(Guid eventIndicatorId)
        {
            byte[] image;

            if (IncidentsChartImages == null)
                return null;

            return IncidentsChartImages.TryGetValue(eventIndicatorId, out image) ? image : null;
        }

        #endregion

        # region Static Images

        private static byte[] _trendArrowDown;
        private static byte[] _trendArrowUp;
        private static byte[] _trendArrowRight;
        public byte[] TrendArrowDown { get { return _trendArrowDown; } }
        public byte[] TrendArrowUp { get { return _trendArrowUp; } }
        public byte[] TrendArrowRight { get { return _trendArrowRight; } }

        private static byte[] _outlookArrowDown;
        private static byte[] _outlookArrowUp;
        private static byte[] _outlookArrowRight;
        public byte[] OutlookArrowDown { get { return _outlookArrowDown; } }
        public byte[] OutlookArrowUp { get { return _outlookArrowUp; } }
        public byte[] OutlookArrowRight { get { return _outlookArrowRight; } }

        static void LoadStaticImages()
        {
            if (_trendArrowDown == null)
                _trendArrowDown = ImagesGenerator.GetJpgImage(@"Images\trend_arrow_down.jpg");

            if (_trendArrowUp == null)
                _trendArrowUp = ImagesGenerator.GetJpgImage(@"Images\trend_arrow_up.jpg");

            if (_trendArrowRight == null)
                _trendArrowRight = ImagesGenerator.GetJpgImage(@"Images\trend_arrow_right.jpg");


            if (_outlookArrowDown == null)
                _outlookArrowDown = ImagesGenerator.GetJpgImage(@"Images\outlook_arrow_down.jpg");

            if (_outlookArrowUp == null)
                _outlookArrowUp = ImagesGenerator.GetJpgImage(@"Images\outlook_arrow_up.jpg");

            if (_outlookArrowRight == null)
                _outlookArrowRight = ImagesGenerator.GetJpgImage(@"Images\outlook_arrow_right.jpg");

        }

        #endregion

        public bool ShowOutlines { get; set; }

        private List<OutlinePosition> _outlinePositions;

        static ControversiesSection()
        {
            LoadStaticImages();
        }

        public GenerationResult GeneratePdfDocument(CompanyReportDataOffline crdo)
        {
            var result = new GenerationResult
            {
                ReportType = crdo.ReportType,
                ReportGeneratorType = ReportGeneratorType.SourcesSection,
                OutlinePositions = new List<OutlinePosition>(),
                PageElementPositions = new List<PageElementPosition>()
            };
            var sw = Stopwatch.StartNew();

            _dataSource = crdo;
            _report = new PdfReport();
         

            LoadEventIndicatorPropertiesVisibilityDictionary();
            LoadControversyIndicators();
            UpdateIncidentLocationsAndTags();

            LoadChartAndMapImages();

            ComposeControversiesSection();

            _outlinePositions = new List<OutlinePosition>();

            AddOutlinePositions();

            if (ShowOutlines)
            {
                if (_outlinePositions.Any())
                {
                    foreach (var parentOutlinePosition in _outlinePositions)
                    {
                        var parentOutline = _report.ParentOutline.ChildOutlines.Add(parentOutlinePosition.Name,
                            new XYDestination(parentOutlinePosition.PageNumber, 0.0f,
                                parentOutlinePosition.VerticalPosition));

                        if (parentOutlinePosition.ChildOutlinePositions == null ||
                            !parentOutlinePosition.ChildOutlinePositions.Any()) continue;

                        foreach (var childOutlinePosition in parentOutlinePosition.ChildOutlinePositions)
                        {
                            var childOutline = parentOutline.ChildOutlines.Add(childOutlinePosition.Name,
                                new XYDestination(childOutlinePosition.PageNumber, 0,
                                    childOutlinePosition.VerticalPosition));

                            if (childOutlinePosition.ChildOutlinePositions == null ||
                            !childOutlinePosition.ChildOutlinePositions.Any()) continue;

                            foreach (var subChildOutlinePosition in childOutlinePosition.ChildOutlinePositions)
                            {
                                childOutline.ChildOutlines.Add(subChildOutlinePosition.Name,
                                    new XYDestination(subChildOutlinePosition.PageNumber, 0,
                                        subChildOutlinePosition.VerticalPosition));
                            }
                        }
                    }
                }
            }

            if (_report.Pages.Any())
                result.PdfDocument = _report.Draw();

            sw.Stop();
            result.OutlinePositions = _outlinePositions;
            result.GenerationTime = sw.Elapsed;

            return result;
        }

        private void AddOutlinePositions()
        {
            if (!_controversyIndicatorLocations.Any()) return;

            var outlinePosition = new OutlinePosition
            {
                Name = "Controversies",
                PageNumber = 1,
                ChildOutlinePositions = new List<OutlinePosition>()
            };

            _outlinePositions.Add(outlinePosition);

            foreach (var controversyIndicatorLocation in _controversyIndicatorLocations)
            {
                var childOutlinePosition = new OutlinePosition
                {
                    Id = controversyIndicatorLocation.ControversyIndicatorId,
                    Name = controversyIndicatorLocation.ControversyIndicatorName,
                    PageNumber = controversyIndicatorLocation.PageNumber,
                    VerticalPosition = controversyIndicatorLocation.Y,
                    ChildOutlinePositions = new List<OutlinePosition>()
                };

                outlinePosition.ChildOutlinePositions.Add(childOutlinePosition);


                var eventIndicatorLocations = _eventIndicatorLocations
                    .Where(eil => eil.ControversyIndicatorId == controversyIndicatorLocation.ControversyIndicatorId)
                    .ToList();

                if (!eventIndicatorLocations.Any()) continue;

                foreach (var eventIndicatorLocation in eventIndicatorLocations)
                {
                    childOutlinePosition.ChildOutlinePositions.Add(
                        new OutlinePosition
                        {
                            Id = eventIndicatorLocation.EventIndicatorId,
                            Name = eventIndicatorLocation.EventIndicatorName,
                            PageNumber = eventIndicatorLocation.PageNumber,
                            VerticalPosition = eventIndicatorLocation.Y
                        });
                }
            }
        }

        private void LoadChartAndMapImages()
        {
            var eventIndicatorIncidents = new Dictionary<Guid, List<Incident>>();
            
            var eventIndicators = _dataSource.EventIndicators.Where(eventIndicator => eventIndicator.AnswerCategory >= 3).ToList();
            
            eventIndicators.ForEach(ei => eventIndicatorIncidents.Add(ei.Id,
                _dataSource.Incidents.Where(i => i.EventIndicatorId == ei.Id).Select(i => new Incident
                {
                    IncidentId = i.IncidentId,
                    IncidentDate = i.IncidentDate,
                    ImpactScore = i.ImpactScore,
                    RiskScore = i.RiskScore
                }).ToList()));

            var imagesGenerator = new ImagesGenerator();

            IncidentsChartImages = imagesGenerator.GetIncidentsChartImages(eventIndicatorIncidents);
        }

        private static void LoadEventIndicatorPropertiesVisibilityDictionary()
        {
            EventIndicatorPropertiesVisibilityDictionary = new Dictionary<int, EventIndicatorPropertiesVisibility>
            {
                {
                    0,
                    new EventIndicatorPropertiesVisibility
                    {
                        IsAssessmentVisible = false,
                        IsImpactVisible = false,
                        IsOutlookVisible = false,
                        IsPreparednessVisible = false,
                        IsRiskVisible = false,
                        IsWorldMapVisible = false
                    }
                },
                {
                    1,
                    new EventIndicatorPropertiesVisibility
                    {
                        IsAssessmentVisible = false,
                        IsImpactVisible = false,
                        IsOutlookVisible = false,
                        IsPreparednessVisible = false,
                        IsRiskVisible = false,
                        IsWorldMapVisible = true
                    }
                },
                {
                    2,
                    new EventIndicatorPropertiesVisibility
                    {
                        IsAssessmentVisible = false,
                        IsImpactVisible = false,
                        IsOutlookVisible = false,
                        IsPreparednessVisible = false,
                        IsRiskVisible = false,
                        IsWorldMapVisible = true
                    }
                },
                {
                    3,
                    new EventIndicatorPropertiesVisibility
                    {
                        IsAssessmentVisible = true,
                        IsImpactVisible = false,
                        IsOutlookVisible = true,
                        IsPreparednessVisible = false,
                        IsRiskVisible = false,
                        IsWorldMapVisible = true
                    }
                },
                {
                    4,
                    new EventIndicatorPropertiesVisibility
                    {
                        IsAssessmentVisible = true,
                        IsImpactVisible = true,
                        IsOutlookVisible = true,
                        IsPreparednessVisible = true,
                        IsRiskVisible = true,
                        IsWorldMapVisible = true
                    }
                },
                {
                    5,
                    new EventIndicatorPropertiesVisibility
                    {
                        IsAssessmentVisible = true,
                        IsImpactVisible = true,
                        IsOutlookVisible = true,
                        IsPreparednessVisible = true,
                        IsRiskVisible = true,
                        IsWorldMapVisible = true
                    }
                }
            };
        }

        private void LoadControversyIndicators()
        {
            ControversyIndicators = new List<ControversyIndicator>();
            
            if (!_dataSource.EventIndicators.Any()) return;

            ControversyIndicators = _dataSource.EventIndicators.Where(ei => ei.ProvidesControversy)
                .Select(ei => new ControversyIndicator
                {
                    Id = ei.ControversyIndicatorId,
                    Name = ei.ControversyIndicatorName,
                    Number = ei.ControversyIndicatorNumber,
                    SortKey = ei.ControversyIndicatorSortKey,
                    CompanyId = ei.CompanyId,
                    AnswerCategory = ei.AnswerCategory,
                    AnswerCategoryScore = ei.AnswerCategoryScore,
                    AnswerCategoryText = ei.AnswerCategoryText,
                    Outlook = ei.OutlookScore
                }).ToList();
        }

        private void ComposeControversiesSection()
        {
            var pages = _report.Pages;
            var x = _report.LeftMargin;

            var pageCount = 0;

            if (!_dataSource.IndicatorTemplates.Any()) return;

            var themes = GetThemes();

            if (!themes.Any()) return;

            foreach (var theme in themes.Where(theme => ThemeHasControversyIndicators(theme.ThemeName)))
            {
                var page = _report.NewPage();
                pages.Add(page);
                pageCount++;

                var remainingHeight = _report.PageMaxHeight;
                float y = 0;

                page.Elements.Add(new Rectangle(x, y, 530, 24, Colors.BarBackgroundColor, Colors.BarBackgroundColor));
                string themeFormattedText = string.Format("<p><font color='FFFFFF'><b>{0} Controversies</b></font></p>", theme.ThemeName);
                page.Elements.Add(new FormattedTextArea(themeFormattedText, x + 5f, y + 3f, 500, 16, FontFamily.Times, 16, false));
                page.Elements.Add(new Line(x, y + 35f, x + 530, y + 35f, 1f, Colors.BarBackgroundColor));

                y = y + 30;
                remainingHeight = remainingHeight - 30;


                var indicators = GetControversyIndicatorsByTheme(theme.ThemeName);

                if (indicators == null) continue;

                foreach (var indicator in indicators)
                {
                    var controversyIndicator = GetControversyIndicator(indicator.Id);

                    if (controversyIndicator == null || controversyIndicator.AnswerCategory <= 0) continue;

                    float estimatedHeight = GetControversyIndicatorHeight(controversyIndicator);

                    CheckRemainingHeight(ref pages, ref page, ref pageCount, ref remainingHeight, estimatedHeight, ref y);

                    _controversyIndicatorLocations.Add(new ControversyIndicatorLocation
                    {
                        ControversyIndicatorId = indicator.Id,
                        ControversyIndicatorName = indicator.Name,
                        PageNumber = pageCount,
                        Y = y
                    });

                    page.Elements.Add(new Rectangle(x, y, 530, 24, RgbColor.Gray, RgbColor.Gray));
                    string indicatorNameFormattedText = string.Format("<p><b>{0}</b></p>", indicator.Name);
                    page.Elements.Add(new FormattedTextArea(indicatorNameFormattedText, x + 5, y + 3, 500f, 15f, FontFamily.Times, 14, false));


                    AddCategoryElement(page.Elements, controversyIndicator.AnswerCategory, x, y + 50f, false);

                    if (controversyIndicator.Outlook.HasValue)
                        AddOutlookElement(page.Elements, controversyIndicator.Outlook.Value, x + 15, y + 100f, 1);

                    var chartHeight = AddControversyIndicatorChart(page.Elements, controversyIndicator, x + 200, y + 50f);

                    if (chartHeight < 85)
                        chartHeight = 85;

                    y = y + chartHeight + 50f;
                    remainingHeight = remainingHeight - chartHeight - 50f;

                    AddStandardText(page.Elements, controversyIndicator.AnswerCategory, x, y);

                    y = y + 15;
                    remainingHeight = remainingHeight - 15;


                    var eventIndicators = GetEventIndicators(controversyIndicator.Id);
                    if (eventIndicators != null && eventIndicators.Count > 0)
                    {
                        foreach (var eventIndicator in eventIndicators.OrderByDescending(ei => ei.AnswerCategory))
                        {
                            if (eventIndicator.AnswerCategory > 0)
                            {
                                if (!EventIndicatorHasIncidents(eventIndicator.Id)) continue;


                                CheckRemainingHeight(ref pages, ref page, ref pageCount, ref remainingHeight, 200, ref y);

                                _eventIndicatorLocations.Add(new EventIndicatorLocation
                                {
                                    ControversyIndicatorId = controversyIndicator.Id,
                                    EventIndicatorId = eventIndicator.BaseEventIndicatorId,
                                    EventIndicatorName = eventIndicator.Name,
                                    PageNumber = pageCount,
                                    Y = y + 5
                                });

                                AddEventIndicatorHeaderElements(eventIndicator, page.Elements, x, y);
                                y = y + 110;
                                remainingHeight = remainingHeight - 110;


                                var eventIndicatorPropertiesVisibility = EventIndicatorPropertiesVisibilityDictionary[eventIndicator.AnswerCategory];

                                if (eventIndicatorPropertiesVisibility.IsOutlookVisible)
                                {
                                    AddOutlookElement(page.Elements, eventIndicator.OutlookScore.Value, x + 15, y, 1);

                                    AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.OutlookText, x + 160f, ref y);
                                    AddEventIndicatorComments(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.OutlookComments, x + 160f, ref y);

                                    y = y + 10;
                                    remainingHeight = remainingHeight - 10;
                                }

                                if (eventIndicatorPropertiesVisibility.IsAssessmentVisible)
                                {
                                    page.Elements.Add(new Label("Assessment", x + 160f, y, 50f, 10f, Font.TimesBold, 10, TextAlign.Left, RgbColor.Black));

                                    y = y + 15;
                                    remainingHeight = remainingHeight - 15;

                                    AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.ControversySummary, x + 160f, ref y);
                                    AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.AnswerCategoryJustification, x + 160f, ref y);
                                }
                                if (eventIndicatorPropertiesVisibility.IsImpactVisible)
                                {
                                    AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.ImpactText, x + 160f, ref y);
                                    AddEventIndicatorComments(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.ImpactComments, x + 160f, ref y);
                                }
                                if (eventIndicatorPropertiesVisibility.IsRiskVisible)
                                {
                                    AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.RiskText, x + 160f, ref y);
                                    AddEventIndicatorComments(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.RiskComments, x + 160f, ref y);
                                }
                                if (eventIndicatorPropertiesVisibility.IsPreparednessVisible)
                                {
                                    AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.PreparednessText, x + 160f, ref y);
                                    AddEventIndicatorComments(ref pages, ref page, ref pageCount, ref remainingHeight, eventIndicator.PreparednessComments, x + 160f, ref y);
                                }

                                if (eventIndicator.AnswerCategory >= 3)
                                {
                                    CheckRemainingHeight(ref pages, ref page, ref pageCount, ref remainingHeight, 140, ref y);

                                    AddIncidentsTimelineChart(eventIndicator, page.Elements, x, y);
                                    y = y + 140;
                                    remainingHeight = remainingHeight - 140;
                                }

                                var incidentId = GetGroupOfIncidentsWithHighestImpactScore(eventIndicator.Id);

                                if (incidentId == string.Empty) continue;

                                var incidents = GetIncidents(eventIndicator.Id, incidentId);

                                if (incidents != null && incidents.Count > 0)
                                {
                                    var isMajorIncident = false;

                                    foreach (var incident in incidents)
                                    {
                                        CheckRemainingHeight(ref pages, ref page, ref pageCount, ref remainingHeight, 100, ref y);

                                        bool showTrend = false;
                                        if (incident.Type == IncidentType.IncidentUpdate || incident.Type == IncidentType.NewsUpdate)
                                            showTrend = true;

                                        if (eventIndicator.AnswerCategory > 2)
                                            isMajorIncident = incident.IsMajorIncident;

                                        AddIncidentBarsElement(page.Elements, isMajorIncident, (int)incident.ImpactScore, (int)incident.RiskScore, showTrend, incident.ImpactTrend, incident.RiskTrend, x, y + 5f);

                                        var incidentName = string.Format(incident.Type == 0
                                            ? "<p><font color='68AAA3'><b>{0}</b></font></p>"
                                            : "<p><font color='68AAA3'><b><i>Update: </i>{0}</b></font></p>", incident.Name);



                                        var incidentNameHeight = 11f;
                                        var incidentNameLenght = Fonts.CalibriBold.GetTextWidth(incident.Name, 11);
                                        if (incidentNameLenght > 350)
                                            incidentNameHeight = 25f;
                                        page.Elements.Add(new FormattedTextArea(incidentName, x + 160f, y + 5f, 375f, incidentNameHeight, Fonts.CalibriFontFamily, 11, false));

                                        y += (incidentNameHeight + 10);

                                        string incidentLabel = "<p>{0} - {1}</p>";
                                        var group = new Group();
                                        if (!string.IsNullOrWhiteSpace(incident.ExternalUrl))
                                        {
                                            var action = new UrlAction(incident.ExternalUrl);
                                            var incidentLink = new Link(x + 160f, y, 375f, 10f, action);
                                            group.Add(incidentLink);
                                            page.Elements.Add(group);
                                            incidentLabel = "<p><font color='FFA500'>{0} - {1}</font></p>";
                                        }
                                        string sourceFormattedText = string.Format(incidentLabel, incident.Source, incident.IncidentDate.ToString("dd MMMM yyy"));
                                        page.Elements.Add(new FormattedTextArea(sourceFormattedText, x + 160f, y, 375f, 10f, Fonts.CalibriFontFamily, 10, false));
                                        y = y + 20;

                                        remainingHeight = remainingHeight - 40;

                                        AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, string.Format("<p>{0}</p>", incident.Summary), x + 160f, ref y);
                                    }
                                }

                                var ids = GetGroupOfIncidentsByDate(eventIndicator.Id, incidentId);

                                if (ids == null) continue;

                                foreach (var id in ids)
                                {
                                    incidents = GetIncidents(eventIndicator.Id, id);

                                    if (incidents == null || incidents.Count <= 0) continue;

                                    var isMajorIncident = false;

                                    page.Elements.Add(new Line(x, y, x + 530, y, 0.5f, RgbColor.Black));

                                    foreach (var incident in incidents)
                                    {
                                        CheckRemainingHeight(ref pages, ref page, ref pageCount, ref remainingHeight, 100, ref y);

                                        bool showTrend = false;
                                        if (incident.Type == IncidentType.IncidentUpdate || incident.Type == IncidentType.NewsUpdate)
                                            showTrend = true;

                                        AddIncidentBarsElement(page.Elements, isMajorIncident, (int)incident.ImpactScore, (int)incident.RiskScore, showTrend, incident.ImpactTrend, incident.RiskTrend, x, y + 5f);

                                        var incidentName = string.Format(incident.Type == 0
                                            ? "<p><font color='68AAA3'><b>{0}</b></font></p>"
                                            : "<p><font color='68AAA3'><b><i>Update: </i>{0}</b></font></p>", incident.Name);

                                        var incidentNameHeight = 11f;
                                        var incidentNameLenght = Fonts.CalibriBold.GetTextWidth(incident.Name, 11);
                                        if (incidentNameLenght > 350)
                                            incidentNameHeight = 25f;

                                        //page.Elements.Add(new FormattedTextArea(incidentName, x + 160f, y + 5f, 500f, 11f, Fonts.CalibriFontFamily, 11, false));
                                        //y = y + 20;

                                        page.Elements.Add(new FormattedTextArea(incidentName, x + 160f, y + 5f, 375f, incidentNameHeight, Fonts.CalibriFontFamily, 11, false));
                                        y += (incidentNameHeight + 10);

                                        string incidentLabel = "<p>{0} - {1}</p>";
                                        var group = new Group();
                                        if (!string.IsNullOrWhiteSpace(incident.ExternalUrl))
                                        {
                                            var action = new UrlAction(incident.ExternalUrl);
                                            var incidentLink = new Link(x + 160f, y, 375, 10f, action);
                                            group.Add(incidentLink);
                                            page.Elements.Add(group);
                                            incidentLabel = "<p><font color='FFA500'>{0} - {1}</font></p>";
                                        }
                                        string sourceFormattedText = string.Format(incidentLabel, incident.Source, incident.IncidentDate.ToString("dd MMMM yyy"));
                                        page.Elements.Add(new FormattedTextArea(sourceFormattedText, x + 160f, y, 375, 10f, Fonts.CalibriFontFamily, 10, false));
                                        y = y + 20;

                                        remainingHeight = remainingHeight - 40;

                                        AddFormattedTextArea(ref pages, ref page, ref pageCount, ref remainingHeight, string.Format("<p>{0}</p>", incident.Summary), x + 160f, ref y);
                                    }
                                }
                            }
                        } // foreach event indicator
                    }
                } // foreach indicators
            }
        }

        private void AddStandardText(Group pageElements, int category, float x, float y)
        {
            string staticFormattedText = "None";

            if (category > 0)
            {
                var severity = GetEventSeverity(category);
                staticFormattedText = string.Format("<p>Based on our event level assessment of impact and risk as {0}, the company has been assigned an overall controversy assessment of category {1}.</p>",
                    severity.ToLowerInvariant(), category);
            }
            
            pageElements.Add(new FormattedTextArea(staticFormattedText, x, y, 530f, 10f, Fonts.CalibriFontFamily, 8.5f, false));
        }

        private void CheckRemainingHeight(ref List<PdfReportPage> pages, ref PdfReportPage page, ref int pageCount, ref float remainingHeight, float estimatedHeight, ref float y)
        {
            if (remainingHeight - estimatedHeight <= 0)
            {
                page = _report.NewPage();
                pages.Add(page);
                pageCount++;

                y = 0;
                remainingHeight = _report.PageMaxHeight;
            }
        }

        private void AddFormattedTextArea(ref List<PdfReportPage> pages, ref PdfReportPage page, ref int pageCount, ref float remainingHeight, string formattedText, float x, ref float y)
        {
            var style = new FormattedTextAreaStyle(Fonts.CalibriFontFamily, 9f, false)
            {
                Paragraph = { Align = TextAlign.Justify, Indent = 0, SpacingAfter = 0, AllowOrphanLines = false }
            };

            var formattedTextArea = new FormattedTextArea(formattedText, x, y, 375f, remainingHeight, style);
            page.Elements.Add(formattedTextArea);

            var requiredHeight = (float)Math.Round((decimal)formattedTextArea.GetRequiredHeight(), 0, MidpointRounding.AwayFromZero);

            remainingHeight = remainingHeight - (requiredHeight + 5);
            y = y + requiredHeight + 5;


            var hasOverflowText = formattedTextArea.HasOverflowText();

            if (hasOverflowText)
            {
                if (y > 700)
                {
                    page = _report.NewPage();
                    pages.Add(page);
                    pageCount++;

                    y = 0;
                    remainingHeight = _report.PageMaxHeight - 25;
                }

                formattedTextArea = formattedTextArea.GetOverflowFormattedTextArea(x, y, remainingHeight);
                if (formattedTextArea != null)
                {
                    page.Elements.Add(formattedTextArea);

                    requiredHeight = (float)Math.Round((decimal)formattedTextArea.GetRequiredHeight(), 0, MidpointRounding.AwayFromZero);

                    remainingHeight = remainingHeight - (requiredHeight + 5);
                    y = y + requiredHeight + 5;
                }
            }
        }

        private void AddEventIndicatorComments(ref List<PdfReportPage> pages, ref PdfReportPage page, ref int pageCount, ref float remainingHeight, List<string> formattedTexts, float x, ref float y)
        {
            var style = new FormattedTextAreaStyle(Fonts.CalibriFontFamily, 9f, false)
            {
                Paragraph = { Align = TextAlign.Justify, Indent = 0, SpacingAfter = 0, AllowOrphanLines = false }
            };

            foreach (var formattedText in formattedTexts)
            {
                var formattedTextArea = new FormattedTextArea(formattedText, x + 10f, y, 365f, remainingHeight, style);
                var requiredHeight = (float)Math.Round((decimal)formattedTextArea.GetRequiredHeight(), 0, MidpointRounding.AwayFromZero);

                CheckRemainingHeight(ref pages, ref page, ref pageCount, ref remainingHeight, requiredHeight + 5f, ref y);

                formattedTextArea = new FormattedTextArea(formattedText, x + 10f, y, 365f, remainingHeight, style);
                page.Elements.Add(new Label("•", x, y, 10f, 10f, Fonts.CalibriBold, 10, TextAlign.Left, RgbColor.Black));
                page.Elements.Add(formattedTextArea);

                remainingHeight = remainingHeight - (requiredHeight + 5);
                y = y + requiredHeight + 5;

                var hasOverflowText = formattedTextArea.HasOverflowText();
                
                if (hasOverflowText)
                {
                    if (y > 700)
                    {
                        page = _report.NewPage();
                        pages.Add(page);
                        pageCount++;

                        y = 0;
                        remainingHeight = _report.PageMaxHeight - 25;
                    }

                    formattedTextArea = formattedTextArea.GetOverflowFormattedTextArea(x + 10f, y, remainingHeight);
                    if (formattedTextArea != null)
                    {
                        page.Elements.Add(formattedTextArea);

                        requiredHeight = (float)Math.Round((decimal)formattedTextArea.GetRequiredHeight(), 0, MidpointRounding.AwayFromZero);

                        remainingHeight = remainingHeight - (requiredHeight + 5);
                        y = y + requiredHeight + 5;
                    }
                }
            }
        }

        private float GetControversyIndicatorHeight(ControversyIndicator controversyIndicator)
        {
            var chartHeight = 35f;

            var eventIndicators = GetEventIndicators(controversyIndicator.Id);

            if (eventIndicators == null || eventIndicators.Count <= 0)
                return chartHeight + 20;

            foreach (var eventIndicator in eventIndicators.OrderByDescending(i => i.AnswerCategory))
            {
                chartHeight = chartHeight + 20f;
            }

            if (chartHeight < 150)
                chartHeight = 150;

            return chartHeight + 90;
        }

        private float AddControversyIndicatorChart(Group pageElements, ControversyIndicator controversyIndicator, float x, float y)
        {
            var chartHeight = 0f;

            pageElements.Add(new Label("Related Events", x, y + 10f, 120f, 10f, Fonts.CalibriBold, 8.5f, TextAlign.Right, RgbColor.Black));

            var xCtg = x + 150;
            for (var ctg = 1; ctg <= 5; ctg++)
            {
                pageElements.Add(new Circle(xCtg + 9, y + 7f, 9f, 9f, Colors.CtgColor[ctg], Colors.CtgColor[ctg], 1, LineStyle.Solid));
                pageElements.Add(new Label(ctg.ToString(CultureInfo.InvariantCulture), xCtg, y, 18f, 16f, Fonts.CalibriBold, 16, TextAlign.Center, RgbColor.White));

                xCtg = xCtg + 40;
            }

            pageElements.Add(new Line(x, y + 25f, x + 330f, y + 25f, 1f, RgbColor.Black));

            var yChart = y + 35f;
            chartHeight += 35f;

            var eventIndicators = GetEventIndicators(controversyIndicator.Id);

            if (eventIndicators == null || eventIndicators.Count <= 0)
                return chartHeight + 20;

            float xItem;

            foreach (var eventIndicator in eventIndicators.OrderByDescending(ei => ei.AnswerCategory).ThenBy(ei => ei.Name))
            {
                pageElements.Add(new Label(eventIndicator.Name, x, yChart, 120f, 10f, Fonts.CalibriLight, 8.5f, TextAlign.Right, RgbColor.Black));

                if (eventIndicator.AnswerCategory > 0)
                {
                    xItem = x + 154 + (eventIndicator.AnswerCategory - 1) * 40;
                    pageElements.Add(new Line(x + 130, yChart + 5f, xItem, yChart + 5f, 1f, Colors.CtgColor[eventIndicator.AnswerCategory]));
                    pageElements.Add(new Circle(xItem + 5, yChart + 5f, 5f, 5f, Colors.CtgColor[eventIndicator.AnswerCategory], RgbColor.White, 1f, LineStyle.Solid));
                }
                else
                {
                    pageElements.Add(new Label("None", x + 130, yChart, 120f, 10f, Fonts.CalibriLight, 8.5f, TextAlign.Left, RgbColor.Black));
                }

                yChart = yChart + 20f;
                chartHeight = chartHeight + 20f;
            }

            pageElements.Add(new Label("Overall Controversy Level", x, yChart, 120f, 10f, Fonts.CalibriBold, 8.5f, TextAlign.Right, RgbColor.Black));

            xItem = x + 154 + (controversyIndicator.AnswerCategory - 1) * 40;
            pageElements.Add(new Line(x + 130, yChart + 5f, xItem, yChart + 5f, 2f, Colors.CtgColor[controversyIndicator.AnswerCategory]));
            pageElements.Add(new Circle(xItem + 5, yChart + 5f, 5f, 5f, Colors.CtgColor[controversyIndicator.AnswerCategory], RgbColor.White, 2f, LineStyle.Solid));

            return chartHeight + 20;
        }

        private void AddEventIndicatorHeaderElements(EventIndicator eventIndicator, Group pageElements, float x, float y)
        {
            pageElements.Add(new Label(eventIndicator.Name, x, y + 5f, 500f, 15f, Font.TimesBold, 14, TextAlign.Left, RgbColor.Black));
            pageElements.Add(new Line(x, y + 25f, x + 530, y + 25f, 1f, RgbColor.Black));

            pageElements.Add(new Circle(x + 20f, y + 53, 20f, 20f, Colors.CtgColor[eventIndicator.AnswerCategory], Colors.CtgColor[eventIndicator.AnswerCategory], 0, LineStyle.Solid));
            pageElements.Add(new Label(eventIndicator.AnswerCategory.ToString("0"), x, y + 53 - 16, 40f, 40f, Fonts.CalibriBold, 35, TextAlign.Center, RgbColor.White));


            pageElements.Add(new Label(string.Format("Category {0}", eventIndicator.AnswerCategory), x + 50f, y + 40f, 50f, 10f, Fonts.CalibriBold, 9, TextAlign.Left, RgbColor.Black));
            pageElements.Add(new Label(GetEventSeverity(eventIndicator.AnswerCategory), x + 50f, y + 55, 50f, 10f, Fonts.CalibriBold, 9, TextAlign.Left, RgbColor.Black));

            var incidentsMapImage = GetIncidentsMapImage(eventIndicator.Id);

            if (incidentsMapImage != null)
                pageElements.Add(new Image(ImageData.GetImage(incidentsMapImage), x + 160f, y + 30f, 0.2f));

            var style = new FormattedTextAreaStyle(Fonts.CalibriFontFamily, 8f, false)
            {
                Paragraph = { Align = TextAlign.Justify, Indent = 0, SpacingAfter = 0, AllowOrphanLines = false }
            };

            var locationsAndTagsFormattedText = string.Format("<p>Locations: {0}</p><p>Tags: {1}</p>", eventIndicator.LocationsText, eventIndicator.Tags);
            pageElements.Add(new FormattedTextArea(locationsAndTagsFormattedText, x + 330f, y + 40f, 200f, 50f, style));
        }

        private void AddIncidentsTimelineChart(EventIndicator eventIndicator, Group pageElements, float x, float y)
        {
            pageElements.Add(new Label(string.Format("{0} Incidents", eventIndicator.Name), x, y + 5f, 500f, 10f, Fonts.CalibriBold, 10, TextAlign.Left, RgbColor.Black));
            pageElements.Add(new Line(x, y + 15f, x + 530, y + 15f, 1f, RgbColor.Black));

            pageElements.Add(new Label("Incidents Timeline", x + 160f, y + 20f, 370f, 10f, Fonts.CalibriRegular, 9f, TextAlign.Center, RgbColor.Black));

            pageElements.Add(new Label("Highest of Impact or Risk", x, y + 50f, 105f, 10f, Fonts.CalibriRegular, 8.5f, TextAlign.Right, RgbColor.Black));
            pageElements.Add(new Label("Main Incident", x, y + 65f, 105f, 10f, Fonts.CalibriRegular, 8.5f, TextAlign.Right, RgbColor.Black));

            pageElements.Add(new Circle(x + 118f, y + 52, 3f, 3f, RgbColor.Black, RgbColor.Black, 1f, LineStyle.Solid));
            pageElements.Add(new Circle(x + 118f, y + 68, 5f, 5f, new RgbColor(125, 23, 4), RgbColor.White, 1f, LineStyle.Solid));

            var incidentsChartImage = GetIncidentsChartImage(eventIndicator.Id);

            if (incidentsChartImage != null)
                pageElements.Add(new Image(ImageData.GetImage(incidentsChartImage), x + 155f, y + 35f, 0.4f));

            pageElements.Add(new Label("Score", x + 150f, y + 85, 50f, 10f, Fonts.CalibriRegular, 9, TextAlign.Left, RgbColor.Black) { Angle = -90 });
        }

        private void AddIncidentBarsElement(Group pageElements, bool isMajorIncident, int impactScore, int riskScore, bool showTrend, int impactTrend, int riskTrend, float x, float y)
        {
            if (isMajorIncident)
            {
                pageElements.Add(new Label("Main Incident", x, y, 120f, 10f, Fonts.CalibriBold, 9, TextAlign.Right, new RgbColor(125, 23, 4)));
                y = y + 15f;
            }

            pageElements.Add(new Label("Impact", x, y, 30f, 10f, Fonts.CalibriRegular, 9, TextAlign.Right, RgbColor.Black));
            pageElements.Add(new Label("Risk", x, y + 15, 30f, 10f, Fonts.CalibriRegular, 9, TextAlign.Right, RgbColor.Black));

            for (int i = 1; i <= 10; i++)
            {
                if (impactScore >= i)
                    pageElements.Add(new Circle(x + 37f, y + 4f, 3f, 3f, RgbColor.Black, new RgbColor(160, 160, 160), 0.5f, LineStyle.Solid));
                else
                    pageElements.Add(new Circle(x + 37f, y + 4f, 3f, 3f, RgbColor.Black, RgbColor.White, 0.5f, LineStyle.Solid));

                if (riskScore >= i)
                    pageElements.Add(new Circle(x + 37f, y + 19f, 3f, 3f, RgbColor.Black, Colors.AzureColor, 0.5f, LineStyle.Solid));
                else
                    pageElements.Add(new Circle(x + 37f, y + 19f, 3f, 3f, RgbColor.Black, RgbColor.White, 0.5f, LineStyle.Solid));

                x += 9;
            }

            if (showTrend)
            {
                x = x + 45f;
                y = y - 1;

                if (impactTrend == 0)
                {
                    pageElements.Add(new Image(ImageData.GetImage(TrendArrowRight), x, y, 0.08f) { Align = Align.Right, VAlign = VAlign.Top });
                }
                if (impactTrend == 1)
                {
                    pageElements.Add(new Image(ImageData.GetImage(TrendArrowUp), x, y, 0.08f) { Align = Align.Right, VAlign = VAlign.Top });
                }
                if (impactTrend == -1)
                {
                    pageElements.Add(new Image(ImageData.GetImage(TrendArrowDown), x, y, 0.08f) { Align = Align.Right, VAlign = VAlign.Top });
                }

                y = y + 15f;


                if (riskTrend == 0)
                {
                    pageElements.Add(new Image(ImageData.GetImage(TrendArrowRight), x, y, 0.08f) { Align = Align.Right, VAlign = VAlign.Top });
                }
                if (riskTrend == 1)
                {
                    pageElements.Add(new Image(ImageData.GetImage(TrendArrowUp), x, y, 0.08f) { Align = Align.Right, VAlign = VAlign.Top });
                }
                if (riskTrend == -1)
                {
                    pageElements.Add(new Image(ImageData.GetImage(TrendArrowDown), x, y, 0.08f) { Align = Align.Right, VAlign = VAlign.Top });
                }
            }
        }

        private void AddCategoryElement(Group pageElements, int category, float x, float y, bool hasLine)
        {
            pageElements.Add(new Circle(x + 20f, y, 20f, 20f, Colors.CtgColor[category], Colors.CtgColor[category], 0, LineStyle.Solid));
            pageElements.Add(new Label(category.ToString("0"), x, y - 16, 40f, 40f, Fonts.CalibriBold, 35, TextAlign.Center, RgbColor.White));

            if (hasLine)
            {
                string categoryFormattedText = string.Format("<p><b>Category {0} - {1}</b></p>", category, GetEventSeverity(category));
                var categoryFormattedTextArea = new FormattedTextArea(categoryFormattedText, x + 45f, y - 14f, 120f, 10f, Fonts.CalibriFontFamily, 9, false);
                pageElements.Add(categoryFormattedTextArea);

                pageElements.Add(new Line(x + 45f, y, x + 180f, y, 0.5f, RgbColor.Black));
            }
            else
            {
                pageElements.Add(new Label(string.Format("Category {0}", category), x + 50, y - 12f, 50f, 10f, Fonts.CalibriBold, 9, TextAlign.Left, RgbColor.Black));
                pageElements.Add(new Label(GetEventSeverity(category), x + 50, y + 2, 50f, 10f, Fonts.CalibriBold, 9, TextAlign.Left, RgbColor.Black));
            }
        }

        private void AddOutlookElement(Group pageElements, int outlook, float x, float y, int type)
        {
            if (type == 0 || type == 1)
            {
                if (outlook == 0)
                    pageElements.Add(new Image(ImageData.GetImage(OutlookArrowRight), x - 15f, y - 20f, 0.08f) { Align = Align.Left, VAlign = VAlign.Top });

                if (outlook == 1)
                    pageElements.Add(new Image(ImageData.GetImage(OutlookArrowUp), x - 15f, y - 20f, 0.08f) { Align = Align.Left, VAlign = VAlign.Top });

                if (outlook == -1)
                    pageElements.Add(new Image(ImageData.GetImage(OutlookArrowDown), x - 15f, y - 20f, 0.08f) { Align = Align.Left, VAlign = VAlign.Top });
            }
            else
            {
                if (outlook == 0)
                    pageElements.Add(new Image(ImageData.GetImage(OutlookArrowRight), x, y, 0.06f) { Align = Align.Left, VAlign = VAlign.Top });

                if (outlook == 1)
                    pageElements.Add(new Image(ImageData.GetImage(OutlookArrowUp), x, y, 0.06f) { Align = Align.Left, VAlign = VAlign.Top });

                if (outlook == -1)
                    pageElements.Add(new Image(ImageData.GetImage(OutlookArrowDown), x, y, 0.06f) { Align = Align.Left, VAlign = VAlign.Top });
            }

            if (type == 0)
            {
                pageElements.Add(new Label("Outlook", x + 35, y - 14f, 50f, 10f, Fonts.CalibriBold, 9, TextAlign.Left, RgbColor.Black));
                pageElements.Add(new Line(x + 35f, y, x + 135f, y, 0.5f, RgbColor.Black));
                pageElements.Add(new Label(GetOutlookAssessment(outlook), x + 35, y + 4, 50f, 10f, Fonts.CalibriRegular, 9, TextAlign.Left, RgbColor.Black));
            }

            if (type == 1)
            {
                pageElements.Add(new Label("Outlook", x + 35f, y - 10f, 50f, 10f, Fonts.CalibriBold, 9, TextAlign.Left, RgbColor.Black));
                pageElements.Add(new Label(GetOutlookAssessment(outlook), x + 35f, y + 2f, 50f, 10f, Fonts.CalibriRegular, 9, TextAlign.Left, RgbColor.Black));
            }

            if (type == 2)
            {
                pageElements.Add(new Label("Outlook", x + 40f, y + 4f, 50f, 10f, Fonts.CalibriBold, 9, TextAlign.Left, RgbColor.Black));
                pageElements.Add(new Label(GetOutlookAssessment(outlook), x + 40f, y + 16f, 50f, 10f, Fonts.CalibriRegular, 9, TextAlign.Left, RgbColor.Black));
            }
        }

        private string GetOutlookAssessment(int outlook)
        {
            switch (outlook)
            {
                case -1:
                    return "Negative";
                case 0:
                    return "Neutral";
                case 1:
                    return "Positive";
                default:
                    return string.Empty;
            }
        }


        public bool EventIndicatorHasIncidents(Guid eventIndicatorId)
        {
            var incidents = _dataSource.Incidents.Where(i => i.EventIndicatorId == eventIndicatorId).ToList();
            return incidents.Any();
        }

        public List<Incident> GetIncidents(Guid eventIndicatorId, string incidentId)
        {
            return _dataSource.Incidents.Where(i => i.EventIndicatorId == eventIndicatorId
                                      && i.IncidentId == incidentId)
                             .OrderByDescending(i => i.IncidentDate)
                             .ToList();
        }

        public string GetGroupOfIncidentsWithHighestImpactScore(Guid eventIndicatorId)
        {
            var incidentGroups = _dataSource.Incidents.Where(i => i.EventIndicatorId == eventIndicatorId)
                                           .GroupBy(i => i.IncidentId)
                                           .Select(group => new
                                           {
                                               IncidentId = group.Key,
                                               HighestScore = Math.Max(group.Max(i => i.ImpactScore), group.Max(i => i.RiskScore))
                                           })
                                           .ToList();

            if (!incidentGroups.Any()) return string.Empty;

            var incidentId = incidentGroups.OrderByDescending(ig => ig.HighestScore)
                                           .Select(ig => ig.IncidentId)
                                           .First();
            return incidentId;
        }

        public List<string> GetGroupOfIncidentsByDate(Guid eventIndicatorId, string incidentId)
        {
            var incidentGroups = _dataSource.Incidents.Where(i => i.EventIndicatorId == eventIndicatorId)
                                           .GroupBy(i => i.IncidentId)
                                           .Select(group => new
                                           {
                                               IncidentId = group.Key,
                                               IncidentDate = group.Max(i => i.IncidentDate)
                                           })
                                           .AsEnumerable();

            if (incidentGroups == null) return null;

            var incidentIds = incidentGroups.Where(i => i.IncidentId != incidentId)
                                            .OrderByDescending(ig => ig.IncidentDate)
                                            .Select(ig => ig.IncidentId)
                                            .ToList();
            return incidentIds;
        }

        private void UpdateIncidentLocationsAndTags()
        {
            if (_dataSource.EventIndicators == null)
                return;

            foreach (var eventIndicator in _dataSource.EventIndicators)
            {
                eventIndicator.Locations = new List<Location>();
                eventIndicator.LocationsText = string.Empty;
                eventIndicator.Tags = string.Empty;

                if (_dataSource.Incidents == null) continue;

                var incidentLocations = _dataSource.Incidents.Where(i => i.EventIndicatorId == eventIndicator.Id)
                                                  .GroupBy(i => new { i.Location.Address, i.Location.Latitude, i.Location.Longitude })
                                                  .Select(group => new Location
                                                  {
                                                      Address = @group.Key.Address,
                                                      Latitude = @group.Key.Latitude,
                                                      Longitude = @group.Key.Longitude
                                                  })
                                                  .ToList();

                if (incidentLocations.Any())
                {
                    StringBuilder locationsText = new StringBuilder();
                    foreach (var incidentLocation in incidentLocations)
                    {
                        eventIndicator.Locations.Add(incidentLocation);
                        locationsText.Append(incidentLocation.Address + ", ");
                    }

                    if (locationsText.Length > 2)
                        eventIndicator.LocationsText = locationsText.Remove(locationsText.Length - 2, 2).ToString();
                }

                var incidentTags = _dataSource.Incidents.Where(i => i.EventIndicatorId == eventIndicator.Id)
                    .GroupBy(i => i.MainTag)
                    .Select(group => @group.Key)
                    .ToList();
                if (incidentTags.Any())
                {
                    eventIndicator.Tags = string.Join(", ", incidentTags);
                }
            }
        }

        public List<EventIndicator> GetEventIndicators(Guid controversyIndicatorId)
        {
            return _dataSource.EventIndicators.Where(ei => ei.ControversyIndicatorId == controversyIndicatorId).ToList();
        }



        public List<Theme> GetThemes()
        {
            return _dataSource.IndicatorTemplates.Where(ti => ti.IsControversyIndicator)
                                     .GroupBy(ti => new
                                     {
                                         ti.ThemeName,
                                         ti.ThemeSortKey
                                     })
                                     .Select(group => new Theme
                                     {
                                         ThemeName = group.Key.ThemeName,
                                         ThemeSortKey = group.Key.ThemeSortKey
                                     })
                                     .OrderBy(t => t.ThemeSortKey)
                                     .ToList();
        }

        public ControversyIndicator GetControversyIndicator(Guid controversyIndicatorId)
        {           
            return ControversyIndicators != null ? ControversyIndicators.SingleOrDefault(ci => ci.Id == controversyIndicatorId) : null;
        }

        public string GetEventSeverity(int category)
        {
            switch (category)
            {
                case 1:
                    return "Low";
                case 2:
                    return "Moderate";
                case 3:
                    return "Significant";
                case 4:
                    return "High";
                case 5:
                    return "Severe";
                default:
                    return string.Empty;
            }
        }

        public List<IndicatorTemplate> GetControversyIndicatorsByTheme(string themeName)
        {
            return _dataSource.IndicatorTemplates.Where(ti => ti.IsControversyIndicator && ti.ThemeName == themeName).ToList();
        }

        public bool ThemeHasControversyIndicators(string themeName)
        {
            var hasControversyIndicators = false;

            var indicators = GetControversyIndicatorsByTheme(themeName);

            if (!indicators.Any()) return false;

            foreach (var indicator in indicators)
            {
                var controversyIndicator = GetControversyIndicator(indicator.Id);

                if (controversyIndicator != null && controversyIndicator.AnswerCategory > 0)
                    hasControversyIndicators = true;
            }

            return hasControversyIndicators;
        }







        public List<Location> CompanyIncidentsLocations { get; set; }

        private void LoadCompanyIncidentsLocations()
        {
            if (_dataSource.Incidents != null)
            {
                CompanyIncidentsLocations = _dataSource.Incidents
                        .GroupBy(i => new {i.Location.Address, i.Location.Latitude, i.Location.Longitude})
                        .Select(group => new Location
                        {
                            Address = group.Key.Address,
                            Latitude = group.Key.Latitude,
                            Longitude = group.Key.Longitude
                        })
                        .ToList();
            }
            else
            {
                CompanyIncidentsLocations = new List<Location>();
            }
        }



    }
}
